package com.sztu.shirocore;

import com.sztu.pojo.ShiroUser;
import com.sztu.service.ShiroUserService;
import com.sztu.token.JwtToken;
import com.sztu.utils.JwtUtil;
import io.jsonwebtoken.Claims;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.Permission;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ShiroUserRealm extends AuthorizingRealm {

    public ShiroUserRealm(){
        super(new HashCredentialsMatcher());
    }

    @Autowired
    private ShiroUserService shiroUserService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JwtToken;
    }

    //鉴权方法
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        Map<String,Object> principal;
        principal=(Map) principals.getPrimaryPrincipal();
        Map<String, List> resAndRoles=shiroUserService.getRolesAndResByAccount((String) principal.get("account"));

        principal.put("roles",resAndRoles.get("roles"));
        principal.put("resource",resAndRoles.get("resource"));

        SimpleAuthorizationInfo authorizationInfo =new SimpleAuthorizationInfo();
        authorizationInfo.addRoles((Collection<String>) resAndRoles.get("roles"));
        authorizationInfo.addStringPermissions((Collection<String>) resAndRoles.get("resource"));
        return authorizationInfo;
    }

    //认证
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        System.out.println("start shiroUserRealm ....");
        JwtToken jwtToken= (JwtToken) token;
        Claims claims= (Claims) JwtUtil.parseToken(jwtToken.getToken());
        String account=claims.getId();
        ShiroUser shiroUser=shiroUserService.getPwdByAccount(account);
        if(shiroUser==null) throw new UnknownAccountException();

        String salt=shiroUser.getSalt();
        String password=shiroUser.getPassword();
        Map<String,Object> principal=new HashMap<>();
        principal.put("account",account);
        principal.put("id",shiroUser.getId());
        return new SimpleAuthenticationInfo(principal,password, ByteSource.Util.bytes(salt),getName());
    }
}
